/* ----------------------------- Noble Steed Engine----------------------------*
Authors : Daniel Randle, Alex Bourne
Date Created : Mar 13 2013

File:
	nsobjectreference.h

Description:
	This file contains the NSObjectReference class which is the base container for all the onjects
	in the game
*---------------------------------------------------------------------------*/

#ifndef NSOBJECTREFERENCE_H
#define NSOBJECTREFERENCE_H

/* ---------------------------------Class NSObjectReference-----------------------------*

Description:
	NSObjectReference will provide a class for the game reference objects

*-------------------------------------------------------------------------------*/

// includes
#include <map>
#include <global.h>
#include <vector>
#include <nsmath3d.h>
#include <nslight.h>
#include <fstream>
#include <string>
#include <Windows.h>

class NSObject;
class NSSpotLight;
class NSPointLight;
class NSShaderSet;
class NSCamera;
class NSObjectSet;
class NSEngine;
class NSBoundingBox;
class NSTexture;

class NSObjectReference
{
public:
	struct Serialize 
	{
		NSVec3Df position;
		NSVec3Df orientation;
		NSVec3Df size;
		bool snap;
	};

	NSObjectReference(NSObject * objPtr = NULL,
		const NSVec3Df & pos = NSVec3Df(),
		const NSVec3Df & orient = NSVec3Df(),
		const NSVec3Df & _scale = NSVec3Df(1.0f,1.0f,1.0f));

	~NSObjectReference();

	void add();

	void decrementID();
	void drawAABB();
	void drawOBB();

	NSBoundingBox * getAABB();
	NSBoundingBox * getOBB();
	NSObject * getBase();
	float getDepth(NSCamera * cam) const;
	unsigned int getID() const;

	NSVec3Df getMoveXYFromMouseNDC( const NSVec2Df & ndcCurrentMousePos, 
		const NSVec2Df & ndcLastMousePos,
		NSCamera * camera);

	NSVec3Df getMoveZFromMouseNDC(const NSVec2Df & ndcCurrentMousePos, 
		const NSVec2Df & ndcLastMousePos, 
		NSCamera * camera);

	NSVec3Df getOrientation() const;
	NSVec3Df getPosition() const;
	NSMatrix4Df getPOVTransform() const;
	NSVec3Df getScale() const;

	bool isSnapToGrid();

	void moveXYFromMouseNDC(const NSVec2Df & ndcCurrentMousePos, const NSVec2Df & ndcLastMousePos, NSCamera * camera);
	void moveZFromMouseNDC(const NSVec2Df & ndcCurrentMousePos, const NSVec2Df & ndcLastMousePos, NSCamera * camera);

	void remove();
	void rotate(const NSVec3Df & amount);
	void rotate(float angX, float angY, float angZ);

	void scale(const NSVec3Df & amount);
	void scale(float scaleX, float scaleY, float scaleZ);
	void setSnapToGrid(bool set);
	void setProjectionMat(const NSMatrix4Df & mat);
	void snapToGrid();

	void translate(const NSVec3Df & amount);
	void translate(float moveX, float moveY, float moveZ);

	virtual void update();
	virtual void serialize(std::ofstream & out);
	virtual void deserialize(std::ifstream & in);

protected:
	NSObject * object;
	unsigned int referenceID;
	bool snap;
	
	NSMatrix4Df projectionMat;
	NSMatrix4Df inverseProjMat;
	NSVec3Df position;
	NSVec3Df orientation;
	NSVec3Df size;

	NSBoundingBox * OBB;
	NSBoundingBox * AABB;

	std::vector<NSVec3Df> aabbVerts;

	CRITICAL_SECTION lock;
};

class NSPointLightReference : public NSObjectReference
{
public:
	struct SerializePointLight : public Serialize
	{
	};

	NSPointLightReference(NSPointLight * objPtr, 
		NSShaderSet * _shaders, 
		const NSVec3Df & pos = NSVec3Df(),
		const NSVec3Df & orient = NSVec3Df(),
		const NSVec3Df & _scale = NSVec3Df(1.0f,1.0f,1.0f));

	~NSPointLightReference();

	void setShaderSet(NSShaderSet * _shaders);

	virtual float getLightScaleFactor();
	virtual NSMatrix4Df getLightTransform();
	virtual void update();

private:
	NSShaderSet * shaders;
	
};

class NSSpotLightReference : public NSPointLightReference
{
public:
	struct SerializedSpotLight : public SerializePointLight
	{
	};

	NSSpotLightReference(NSSpotLight * objPtr, 
		NSShaderSet * _shaders, 
		const NSVec3Df & pos = NSVec3Df(),
		const NSVec3Df & orient = NSVec3Df(),
		const NSVec3Df & _scale = NSVec3Df(1.0f,1.0f,1.0f));

	~NSSpotLightReference();

	virtual float getLightScaleFactor();
	virtual NSMatrix4Df getLightTransform();
	virtual void update();
};

#endif